package wps.mojo.utils;

import java.io.File;
import java.io.FileInputStream;
import java.util.List;

import org.apache.commons.io.IOUtils;
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.Namespace;
import org.dom4j.Node;
import org.dom4j.QName;

/**
 * @Author : <a href="mailto:Juanyong.zhang@gmail.com">Cham Juanyong.zhang</a>
 * @Date : Mar 28, 2011
 */
public class Dom4jUtils {
	@SuppressWarnings("unchecked")
	public static void removeAllNamespaces(Document doc) {
		Element root = doc.getRootElement();
		if (root.getNamespace() != Namespace.NO_NAMESPACE) {
			removeNamespaces(root.content());
		}
	}

	@SuppressWarnings("unchecked")
	public static void unfixNamespaces(Document doc, Namespace original) {
		Element root = doc.getRootElement();
		if (original != null) {
			setNamespaces(root.content(), original);
		}
	}

	public static void setNamespace(Element elem, Namespace ns) {

		elem.setQName(QName.get(elem.getName(), ns, elem.getQualifiedName()));
	}

	/**
	 * Recursively removes the namespace of the element and all its children:
	 * sets to Namespace.NO_NAMESPACE
	 */
	public static void removeNamespaces(Element elem) {
		setNamespaces(elem, Namespace.NO_NAMESPACE);
	}

	/**
	 * Recursively removes the namespace of the list and all its children: sets
	 * to Namespace.NO_NAMESPACE
	 */
	public static void removeNamespaces(List<Node> l) {
		setNamespaces(l, Namespace.NO_NAMESPACE);
	}

	/**
	 * Recursively sets the namespace of the element and all its children.
	 */
	@SuppressWarnings("unchecked")
	public static void setNamespaces(Element elem, Namespace ns) {
		setNamespace(elem, ns);
		setNamespaces(elem.content(), ns);
	}

	/**
	 * Recursively sets the namespace of the List and all children if the
	 * current namespace is match
	 */
	public static void setNamespaces(List<Node> l, Namespace ns) {
		Node n = null;
		for (int i = 0; i < l.size(); i++) {
			n = (Node) l.get(i);

			if (n.getNodeType() == Node.ATTRIBUTE_NODE) {
				((Attribute) n).setNamespace(ns);
			}
			if (n.getNodeType() == Node.ELEMENT_NODE) {
				setNamespaces((Element) n, ns);
			}
		}
	}

	public static String queryXML(File dom, String query) throws Exception {
		String value = "";
		Document doc = DocumentHelper.parseText(IOUtils
				.toString(new FileInputStream(dom)));

		removeAllNamespaces(doc);

		Node node = doc.selectSingleNode(query);

		if (null != node) {
			value = node.getText();
		} else {
			throw new Exception("XPath: " + query + " is not found in file: "
					+ dom.getPath());
		}

		return value;
	}

}
